#include "udpServer.hpp"
#include "User.hpp"
using namespace Server;
#include <memory>
#include <unordered_map>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fstream>
#include <signal.h>

// const string filepath = "./myfile.txt";

// unordered_map<string, string> dick;

static void Uasge()
{
    cout << "Usage\n\t"
         << "local_port error" << endl;
}
// static bool Cutstring(string &line, string *key, string *value, const string sep)
// {
//     auto pos = line.find(sep);
//     if (pos == string::npos)
//         return false;
//     *key = line.substr(0, pos);             //[])
//     *value = line.substr(pos + sep.size()); //(]
//     return true;
// }
// static void InitDict()
// {
//     ifstream in(filepath, std::ios::binary);
//     if (!in.is_open())
//     {
//         cerr << "open file error" << errno << " : " << strerror(errno) << endl;
//         exit(OPEN_ERROR);
//     }
//     string line;
//     string key, value;
//     while (getline(in, line))
//     {
//         if (Cutstring(line, &key, &value, ":"))
//             dick.insert(make_pair(key, value));
//     }
//     in.close();
//     cout << "load dict success" << endl;
// }

// static void debugPrint()
// {
//     for (auto &dt : dick)
//     {
//         cout << dt.first << " : " << dt.second << endl;
//     }
// }
// static void reload(int signo)
// {
//     (void)signo;
//     InitDict();
// }

// static void handlemessage(const int sockfd, const string &clientip, const uint16_t &clientport, const string &message)
// {
//     // 在这里对业务逻辑进行处理,在返回回去
//     string response_message; // 返回的字符串函数

//     auto iter = dick.find(message);
//     if (iter == dick.end())
//         response_message = "unknown";
//     else
//         response_message = iter->second;

//     // 开始返回
//     struct sockaddr_in respose;
//     bzero(&respose, sizeof(respose)); // 记得清空
//     respose.sin_family = AF_INET;
//     respose.sin_port = htons(clientport);
//     respose.sin_addr.s_addr = inet_addr(clientip.c_str());
//     sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr *)&respose, sizeof(respose));
// }

// // demo2 解析文件命令
// static void execCmd(const int sockfd, const string &clientip, const uint16_t &clientport, const string &cmd)
// {
//     // 需要禁止掉几个命令

//     if (cmd.find("rm") != string::npos || cmd.find("cd") != string::npos || cmd.find("rmdir") != string::npos)
//     {
//         cerr << clientip << "+" << clientport << "正在执行非法操作" << cmd << endl;
//         return;
//     }
//     // popen = exec+fork+pipe
//     // 1. cmd解析，ls -a -l
//     // 2. 如果必要，可能需要fork, exec*
//     string response_message;
//     FILE *fp = popen(cmd.c_str(), "r");
//     if (fp == nullptr)
//     {
//         cout << "cmd error" << errno << endl;
//     }
//     char buffer[1024];
//     while (fgets(buffer, sizeof(buffer), fp))
//     {
//         response_message+=buffer;
//     }
//     pclose(fp);   //记得关闭这个文件描述符
//     // 开始返回
//     struct sockaddr_in respose;
//     bzero(&respose, sizeof(respose)); // 记得清空
//     respose.sin_family = AF_INET;
//     respose.sin_port = htons(clientport);
//     respose.sin_addr.s_addr = inet_addr(clientip.c_str());
//     sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr *)&respose, sizeof(respose));
// }

// demo3 --udp聊天
Users onlineusers;
static void chartUdp(const int sockfd, const string &clientip, const uint16_t &clientport, const string &message)
{
    // 首先判断是否在线上
    if (message == "online")
        onlineusers.addUser(clientip, clientport);
    if (message == "offline")
        onlineusers.delUser(clientip, clientport);

    if (onlineusers.isOnline(clientip, clientport))
    {
        // 开始广播消息
        onlineusers.broadcastMessage(sockfd,clientip,clientport,message);
    }
    else
    {
        // 只给他单独发消息
        string response_message = "您还没有上线，输入online即可上线交流";

        struct sockaddr_in respose;
        bzero(&respose, sizeof(respose)); // 记得清空
        respose.sin_family = AF_INET;
        respose.sin_port = htons(clientport);
        respose.sin_addr.s_addr = inet_addr(clientip.c_str());
        sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr *)&respose, sizeof(respose));
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Uasge();
        exit(USAGE_ERROR);
    }
    // signal(2,reload);
    // InitDict();
    //  debugPrint();
    uint16_t serverport = atoi(argv[1]);
    // unique_ptr<udpserver> se_ptr(new udpserver(handlemessage, serverport));  //翻译
    // unique_ptr<udpserver> se_ptr(new udpserver(execCmd, serverport));           //解析命令
    unique_ptr<udpserver> se_ptr(new udpserver(chartUdp, serverport)); // 线上聊天

    se_ptr->initServer();
    se_ptr->startServer();
    return 0;
}